package com.demo.consumer;

import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.io.IOException;

/**
 * @author lkz
 * @version 1.0.0
 * @ClassName FanoutConsumer.java
 * @Description TODO
 * @createTime 2022年04月08日 23:41:00
 */
@Component
public class FanoutConsumer {

    @RabbitListener(bindings = @QueueBinding( //绑定队表和交换机
            value = @Queue("fanout_queue1"),//绑定队列
             exchange = @Exchange(name="logs",type = ExchangeTypes.FANOUT) //绑定交换 机和声明交换机类型
             ))
    public void receive1(String msg, Channel channel, Message message) throws IOException {
        try {
            // 消息自定义id 可以在传发送 消息的时候设置
            //message.getMessageProperties().setMessageId(uuid);
            String messageId = message.getMessageProperties().getMessageId();

            System.out.println("receive1 = " + msg);
            /**
             * basicAck 手动签收
             * 参数一 消息投递 ID 同一条消息重新进入队列会被重新赋予消息编号
             * 参数二 表示 是否批量消费
             */
            channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
        }catch (Exception e){
            /**
             * 参数一 标识消息id
             * 参数二 表示 是否批量消费
             * 参数三 为true时重会队列 false 丢失消息
             */
            String s = new String(message.getBody(), "utf-8");
            channel.basicNack(message.getMessageProperties().getDeliveryTag(),false,true);

            // 以下是补充的sgu2024
            // 获取当前消息是否是重复投递的
            //      redelivered 为 true：说明当前消息已经重复投递过一次了
            //      redelivered 为 false：说明当前消息是第一次投递
            //Boolean redelivered = message.getMessageProperties().getRedelivered();

            // 核心操作失败：返回 NACK 信息
            // requeue 参数：控制消息是否重新放回队列
            //      取值为 true：重新放回队列，broker 会重新投递这个消息
            //      取值为 false：不重新放回队列，broker 会丢弃这个消息

//            if (redelivered) {
//                // 如果当前消息已经是重复投递的，说明此前已经重试过一次啦，所以 requeue 设置为 false，表示不重新放回队列
//                channel.basicNack(deliveryTag, false, false);
//            } else {
//                // 如果当前消息是第一次投递，说明当前代码是第一次抛异常，尚未重试，所以 requeue 设置为 true，表示重新放回队列在投递一次
//                channel.basicNack(deliveryTag, false, true);
//            }


        }

    }

    @RabbitListener(bindings = @QueueBinding( value = @Queue("fanout_queue2"),
             exchange= @Exchange(name = "logs", type = ExchangeTypes.FANOUT)))
    public void receive2(String message) {
        System.out.println("receive2 = " + message);
    }

}
